package demo;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 苏李涛
 * Date: 2024-11-03
 * Time: 18:37
 */
public class UdpEchoServer {
    private DatagramSocket socket = null;

    //指定一个固定端口port,让服务器来使用
    public UdpEchoServer(int port) throws SocketException {
        socket = new DatagramSocket(port);
    }

    public void start() throws IOException {
        // 启动服务器
        System.out.println("启动服务器");
        while (true){

            /**
             * 循环一次, 就相当于处理一次请求.
             * 处理请求的过程, 典型的服务器都是分成三个步骤的.
             * 1.读取请求并解析.
             * 2.根据请求, 计算响应. (服务器最关键的逻辑)
             * 3. 把响应返回给客户端
             * 4. 打印一个日志
             */
//            1.读取请求并解析.
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
            socket.receive(requestPacket);//从网卡（文件）里读出请求
            String request = new String(requestPacket.getData(),0,requestPacket.getLength());
//          把读取到的二进制数据, 转成字符串. 只是构造有效的部分.

//            2.根据请求, 计算响应. (服务器最关键的逻辑)
//            由于该服务器是回显是服务器，这个环节相当于省略了
            String response = process(request);

//            3. 把响应返回给客户端
//            根据 response 构造 DatagramPacket, 发送给客户端.
//            此处不能使用 response.length()
//            注意： UDP 协议自身没有保存对方的信息，要使用requestPacket.getSocketAddress()指定对方的端口信息
            DatagramPacket responsePack = new DatagramPacket(response.getBytes(),response.getBytes().length,
                    requestPacket.getSocketAddress());
            socket.send(requestPacket);


//            4. 打印一个日志
            System.out.printf("[%s:%d] req:%s, resp: %s\n",requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);

        }
    }

    // 后续如果要写别的服务器, 只修改这个地方就好了.
    private String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        UdpEchoServer server = new UdpEchoServer(7070);
        server.start();
    }
}
